﻿using Domain.Entity;
using DtoFw;
using DtoFw.Enum;
using DtoFw.Query;
using DtoFw.Result;
using Microsoft.Extensions.Logging;
using Repository;
using Service.Base;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Util;

namespace Service
{
    public class EarlyWarningService : BaseService
    {
        /// <summary>
        /// 字典的备注分隔符
        /// </summary>
        private const string DicRemarkSeparator = "#####";

        private readonly NoticeLogRepository _noticeLogRepository;
        private readonly MainDicRepository _mainDicRepository;
        private readonly RoomBoxRepository _roomBoxRepository;
        private readonly WarnEnvironmentRepository _warnEnvironmentRepository;
        private readonly NotificationRepository _notificationRepository;
        private readonly MainConfigRepository _mainConfigRepository;
        private readonly CasePhysicalEvidenceRepository _casePhysicalEvidenceRepository;
        private readonly CasePhysicalEvidenceTransfereRepository _casePhysicalEvidenceTransfereRepository;
        private readonly MainUserRepository _userRepository;
        private ILogger<EarlyWarningService> _logger;

        /// <summary>
        /// 构造函数
        /// </summary>
        public EarlyWarningService(NoticeLogRepository noticeLogRepository, MainDicRepository mainDicRepository, RoomBoxRepository roomBoxRepository, WarnEnvironmentRepository warnEnvironmentRepository, CasePhysicalEvidenceTransfereRepository casePhysicalEvidenceTransfereRepository, CasePhysicalEvidenceRepository casePhysicalEvidenceRepository, NotificationRepository notificationRepository, MainConfigRepository mainConfigRepository, ILogger<EarlyWarningService> logger, MainSerialNumberRepository mainSerialNumberRepository, MainUserRepository userRepository) : base(mainSerialNumberRepository)
        {
            _noticeLogRepository = noticeLogRepository;
            _mainDicRepository = mainDicRepository;
            _roomBoxRepository = roomBoxRepository;
            _warnEnvironmentRepository = warnEnvironmentRepository;
            _casePhysicalEvidenceTransfereRepository = casePhysicalEvidenceTransfereRepository;
            _casePhysicalEvidenceRepository = casePhysicalEvidenceRepository;
            _notificationRepository = notificationRepository;
            _mainConfigRepository = mainConfigRepository;
            _logger = logger;
            _userRepository = userRepository;
        }

        #region 预警内部接口

        /// <summary>
        /// 物证未绑定
        /// </summary>
        /// <returns>是否成功</returns>
        public bool EarlyWarnEvidenceUnbound()
        {
            try
            {
                //if (!GetStatus<NoBindTagDtoWarning>(WarningCategory.NoBindTagDtoWarning, out NoBindTagDtoWarning noBindTagDtoWarning)) return false;
                if (!GetStatus(out ConfigRequestDto configRequestDto)) return false;
                NoBindTagDtoWarning noBindTagDtoWarning = configRequestDto.noBindTagDtoWarning;

                if (!noBindTagDtoWarning.Status) return false;
                int minutes = noBindTagDtoWarning.Minute;

                //查询上一次的起止日期
                DateTime dt = GetMaxCreateTime(EalyWarnTypeEnum.eNoBindWarning);

                List<CasePhysicalEvidenceEntity> entityList = _notificationRepository.GetDb().Queryable<CasePhysicalEvidenceEntity>()
                       .Where(v => v.CreateTime >= dt && v.CreateTime <= DateTime.Now.AddMinutes(-minutes) && string.IsNullOrWhiteSpace(v.RFID)).ToList();

                WebScoketReqDto dto = new WebScoketReqDto();

                string influence = "物品未绑定";
                string treatmentMethod = "请进行绑定";
                if (GetDicRemark(EalyWarnTypeEnum.eNoBindWarning, out string temp1, out string temp2))
                {
                    influence = temp1;
                    treatmentMethod = temp2;
                }

                foreach (var entity in entityList)
                {
                    string content = string.Format($"{noBindTagDtoWarning.PopContent}", entity.Name, entity.No);
                    _notificationRepository.GetDb().Insertable(new NotificationEntity()
                    {
                        Mold = (int)EalyWarnTypeEnum.eNoBindWarning,
                        NoticeTime = DateTime.Now,
                        Describe = content,
                        Level = 3,
                        IsHandle = 1,
                        IsIgnore = 1,
                        Influence = influence,
                        TreatmentMethod = treatmentMethod,
                        OrganId = entity.OrganId,
                        OrganName = entity.OrganName,
                        ComNo = entity.ComNo,
                        CheckId = entity.Id, // 物品ID
                        CreateTime = DateTime.Now,
                        IsDeleted = false
                    }).ExecuteCommandAsync();

                    //推送
                    dto.webScoketContents.Add(new WebScoketContent
                    {
                        Mold = (int)EalyWarnTypeEnum.eNoBindWarning,
                        MolldTitle = "物品未绑定",
                        NoticeTime = DateTime.Now,
                        Describe = content,
                        Level = 3,
                    });
                }
                if(entityList.Count > 0)
                {
                    SendWarning(dto, entityList.Select(v=>v.CreatorId.Value).ToList()); // 数据推送UI
                }
            }
            catch (Exception ex)
            {
                return false;
            }
            return true;
        }

        /// <summary>
        /// 未及时入库
        /// </summary>
        /// <returns>是否成功</returns>
        public bool EarlyWarnOvertimeStock()
        {
            try
            {
                //if (!GetStatus<OvertimeStockWarning>(WarningCategory.OvertimeStockWarning, out OvertimeStockWarning overtimeStockWarning)) return false;
                if (!GetStatus(out ConfigRequestDto configRequestDto)) return false;
                var overtimeStockWarning = configRequestDto.overtimeStockWarning;

                if (!overtimeStockWarning.Status) return false;

                int minutes = overtimeStockWarning.Minute;

                //查询上一次的起止日期
                DateTime dt = GetMaxCreateTime(EalyWarnTypeEnum.eOvertimeStockWarning);

                List<CasePhysicalEvidenceEntity> entityList = _notificationRepository.GetDb().Queryable<CasePhysicalEvidenceEntity>()
                       .Where(v => v.CreateTime >= dt && v.CreateTime <= DateTime.Now.AddMinutes(-minutes) && v.Status == 0).ToList(); // 0已登记

                WebScoketReqDto dto = new WebScoketReqDto();

                string influence = "未及时入库";
                string treatmentMethod = "请及时入库";
                if (GetDicRemark(EalyWarnTypeEnum.eOvertimeStockWarning, out string temp1, out string temp2))
                {
                    influence = temp1;
                    treatmentMethod = temp2;
                }

                foreach (var entity in entityList)
                {
                    string content = string.Format($"{overtimeStockWarning.PopContent}", entity.Name, entity.No);
                    _notificationRepository.GetDb().Insertable(new NotificationEntity()
                    {
                        Mold = (int)EalyWarnTypeEnum.eOvertimeStockWarning,
                        NoticeTime = DateTime.Now,
                        Describe = content,
                        Level = 3,
                        IsHandle = 1,
                        IsIgnore = 1,
                        Influence = influence,
                        TreatmentMethod = treatmentMethod,
                        OrganId = entity.OrganId,
                        OrganName = entity.OrganName,
                        ComNo = entity.ComNo,
                        CheckId = entity.Id, // 物品ID
                        CheckTime = entity.CreateTime, // 登记时间
                        CreateTime = DateTime.Now,
                        IsDeleted = false
                    }).ExecuteCommandAsync();

                    //推送
                    dto.webScoketContents.Add(new WebScoketContent
                    {
                        Mold = (int)EalyWarnTypeEnum.eOvertimeStockWarning,
                        MolldTitle = "未及时入库",
                        NoticeTime = DateTime.Now,
                        Describe = content,
                        Level = 3,
                    });
                }
                if (entityList.Count > 0)
                {
                    SendWarning(dto, entityList.Select(v => v.CreatorId.Value).ToList()); // 数据推送UI
                }

            }
            catch (Exception ex)
            {
                return false;
            }

            return true;
        }

        /// <summary>
        /// 未及时回库
        /// </summary>
        /// <returns>是否成功</returns>
        public bool EarlyWarnOvertimeRevert()
        {
            try
            {
                // if (!GetStatus<OvertimeRevertWarning>(WarningCategory.OvertimeRevertWarning, out OvertimeRevertWarning overtimeRevertWarning)) return false;
                if (!GetStatus(out ConfigRequestDto configRequestDto)) return false;
                var overtimeRevertWarning = configRequestDto.overtimeRevertWarning;

                if (!overtimeRevertWarning.Status) return false;
                int residueMinute = overtimeRevertWarning.ResidueMinute;
                int beOverdueMinute = overtimeRevertWarning.BeOverdueMinute;

                //查询上一次的起止日期
                DateTime dt = GetMaxCreateTime(EalyWarnTypeEnum.eOvertimeRevertWarning);

                List<CasePhysicalEvidenceTransfereEntity> entityList = _casePhysicalEvidenceTransfereRepository.GetDb().Queryable<CasePhysicalEvidenceTransfereEntity>()
                    .Where(v => !v.IsDeleted && v.DeliveryDicType == 1 && v.HistoryStatus == 1 && v.CreateTime >= dt
                        && ((overtimeRevertWarning.ResidueChecked && v.ReturnTime != null && v.ReturnTime >= DateTime.Now.AddMinutes(residueMinute)) // 剩余时间提醒
                        || (overtimeRevertWarning.BeOverdueChecked && v.ReturnTime != null && v.ReturnTime <= DateTime.Now.AddMinutes(-beOverdueMinute)))) // 逾期提醒
                     .ToList();

                WebScoketReqDto dto = new WebScoketReqDto();

                string influence = "未及时回库";
                string treatmentMethod = "请及时回库";
                if (GetDicRemark(EalyWarnTypeEnum.eOvertimeRevertWarning, out string temp1, out string temp2))
                {
                    influence = temp1;
                    treatmentMethod = temp2;
                }

                foreach (var entity in entityList)
                {
                    string content = string.Empty;
                    var caseEvidence = _casePhysicalEvidenceTransfereRepository.GetDb().Queryable<CasePhysicalEvidenceEntity>().Where(v => v.Id == entity.EvidenceId).First();
                    if (caseEvidence != null)
                    {
                        content = string.Format($"{overtimeRevertWarning.PopContent}", caseEvidence.Name, caseEvidence.No);
                    }

                    _notificationRepository.GetDb().Insertable(new NotificationEntity()
                    {
                        Mold = (int)EalyWarnTypeEnum.eOvertimeRevertWarning,
                        NoticeTime = DateTime.Now,
                        Describe = content,
                        Level = 3,
                        IsHandle = 1,
                        IsIgnore = 1,
                        Influence = influence,
                        TreatmentMethod = treatmentMethod,
                        OrganId = entity.OrganId,
                        OrganName = entity.OrganName,
                        ComNo = entity.ComNo,
                        CheckId = entity.EvidenceId, // 物品ID
                        CheckTime = entity.ReturnTime, // 回库时间
                        CreateTime = DateTime.Now,
                        IsDeleted = false
                    }).ExecuteCommandAsync();

                    //推送
                    dto.webScoketContents.Add(new WebScoketContent
                    {
                        Mold = (int)EalyWarnTypeEnum.eOvertimeRevertWarning,
                        MolldTitle = "未及时回库",
                        NoticeTime = DateTime.Now,
                        Describe = content,
                        Level = 3,
                    });
                }
                if (entityList.Count > 0)
                {
                    SendWarning(dto, entityList.Select(v => v.CreatorId.Value).ToList()); // 数据推送UI
                }
                return true;
            }
            catch (Exception ex)
            {
                return false;
            }
        }

        /// <summary>
        /// 根据RFID获取物品是否入库(处理异常出库)
        /// </summary>
        /// <param name="rfidList">物品RFID</param>
        /// <returns>是否入库</returns>
        public BaseGenericResult<bool> GetEvidenceStockStatus(List<string> rfidList)
        {
            try
            {
                //if (!GetStatus<UnusualLevelWarning>(WarningCategory.UnusualLevelWarning, out UnusualLevelWarning unusualLevelWarning)) return new BaseGenericResult<bool>(false);
                if (!GetStatus(out ConfigRequestDto configRequestDto)) return new BaseGenericResult<bool>(false);
                var unusualLevelWarning = configRequestDto.unusualLevelWarning;

                if (!unusualLevelWarning.Status) return new BaseGenericResult<bool>(false);

                List<CasePhysicalEvidenceEntity> entityList = _casePhysicalEvidenceRepository.GetDb().Queryable<CasePhysicalEvidenceEntity>()
                    .Where(v => rfidList.Contains(v.RFID) && v.Status == 1).ToList(); // 1 已入库

                if (entityList.Count > 0)
                {
                    WebScoketReqDto dto = new WebScoketReqDto();

                    string influence = "异常出库";
                    string treatmentMethod = "请及时处理异常出库";
                    if (GetDicRemark(EalyWarnTypeEnum.eUnusualLevelWarning, out string temp1, out string temp2))
                    {
                        influence = temp1;
                        treatmentMethod = temp2;
                    }

                    foreach (var entity in entityList)
                    {
                        string content = string.Format($"{unusualLevelWarning.PopContent}", entity.Name, entity.No);
                        var notification = new NotificationEntity()
                        {
                            Mold = (int)EalyWarnTypeEnum.eUnusualLevelWarning,
                            NoticeTime = DateTime.Now,
                            Describe = content,
                            Level = 1,
                            IsHandle = 1,
                            IsIgnore = 1,
                            Influence = influence,
                            TreatmentMethod = treatmentMethod,
                            OrganId = entity.OrganId,
                            OrganName = entity.OrganName,
                            ComNo = entity.ComNo,
                            CheckId = entity.Id, // 物品ID
                            CreateTime = DateTime.Now,
                            IsDeleted = false
                        };
                        _notificationRepository.GetDb().Insertable(notification).ExecuteCommandAsync();

                        //推送
                        dto.webScoketContents.Add(new WebScoketContent
                        {
                            Mold = (int)EalyWarnTypeEnum.eUnusualLevelWarning,
                            MolldTitle = "异常出库",
                            NoticeTime = DateTime.Now,
                            Describe = content,
                            Level = 1,
                        });
                    }
                    if (entityList.Count > 0)
                    {
                        SendWarning(dto, entityList.Select(v => v.CreatorId.Value).ToList()); // 数据推送UI
                    }
                }

                return new BaseGenericResult<bool>(entityList.Count > 0);
            }
            catch(Exception ex)
            {
                return new BaseGenericResult<bool>(false);
            }
        }

        /// <summary>
        /// 处理环境报警
        /// </summary>
        /// <param name="warnEnvironmentEntityList">环境信息</param>
        /// <returns>是否成功</returns>
        public BaseGenericResult<bool> HandleWarnEnvironment(List<WarnEnvironmentEntity> warnEnvironmentEntityList)
        {
            try
            {
                if (warnEnvironmentEntityList?.Count < 1) 
                    return new BaseGenericResult<bool>(false);
                //if (!GetStatus<EnvironmentalWarning>(WarningCategory.EnvironmentalWarning, out EnvironmentalWarning environmentalWarning)) return new BaseGenericResult<bool>(false);
                if (!GetStatus(out ConfigRequestDto configRequestDto)) return new BaseGenericResult<bool>(false);
                var environmentalWarning = configRequestDto.environmentalWarning;

                //if (!environmentalWarning.Status) return false;

                var groupList = warnEnvironmentEntityList.GroupBy(x => x.Mold);
                var organId = warnEnvironmentEntityList[0].OrganId;
                //查询单位的所有用户
                var userIds = _userRepository.Query(v => v.OrgId == organId).Select(v => v.Id).ToList();
                //删除72小时之前的数据
                _warnEnvironmentRepository.Delete(DateTime.Now.AddDays(-3));
                // 结果信息
                List<bool> retList = new List<bool>();

                WebScoketReqDto dto = new WebScoketReqDto();
                foreach (var group in groupList)
                {
                    var entity = group.ToList().Find(f => f.CreateTime == group.Max(x => x.CreateTime));
                    
                    EalyWarnTypeEnum ealyWarnTypeEnum = (EalyWarnTypeEnum)entity.Mold;

                    bool isWarn = false;
                    string content = string.Empty;
                    if (double.TryParse(entity.ValInfo, out double temp))
                    {
                        entity.ValInfo = temp.ToString("0.0");
                        switch (ealyWarnTypeEnum)
                        {
                            case EalyWarnTypeEnum.eTemperatureWarning:
                                if (!environmentalWarning.TemperaturChecked)//未开启直接跳过
                                    continue;
                                isWarn = temp >= environmentalWarning.TallTemperature || temp <= environmentalWarning.LowTemperature;
                                content = string.Format($"{environmentalWarning.TemperatureContent}", entity.Area, entity.ValInfo);
                                entity.Source = "温度传感器";
                                break;
                            case EalyWarnTypeEnum.eHumidityWarning:
                                if (!environmentalWarning.HumidityChecked)//未开启直接跳过
                                    continue;
                                isWarn = temp >= environmentalWarning.TallHumidity || temp <= environmentalWarning.LowHumidity;
                                content = string.Format($"{environmentalWarning.HumidityContent}", entity.Area, entity.ValInfo);
                                entity.Source = "湿度传感器";
                                break;
                            case EalyWarnTypeEnum.eSmokeWarning:
                                if (!environmentalWarning.SmogChecked)//未开启直接跳过
                                    continue;
                                isWarn = temp >= 100; // 烟感会自己报警，大于100就认为报警了
                                content = string.Format($"{environmentalWarning.SmogContent}", entity.Area, entity.ValInfo);
                                entity.Source = "烟感传感器";
                                break;
                            case EalyWarnTypeEnum.eWaterWarning:
                                if (!environmentalWarning.WaterChecked)//未开启直接跳过
                                    continue;
                                isWarn = temp >= 100; // 水侵会自己报警，大于100就认为报警了
                                content = string.Format($"{environmentalWarning.WaterContent}", entity.Area, entity.ValInfo);
                                entity.Source = "水侵传感器";
                                break;
                            case EalyWarnTypeEnum.eAirWarning:
                                if (!environmentalWarning.AirChecked)//未开启直接跳过
                                    continue;
                                isWarn = temp >= environmentalWarning.TallAir || temp <= environmentalWarning.LowAir;
                                content = string.Format($"{environmentalWarning.AirContent}", entity.Area, entity.ValInfo);
                                entity.Source = "空气质量传感器";
                                break;
                        }
                    }
                    entity.IsDeleted = isWarn;
                    // 写环境数据
                    int enId = _warnEnvironmentRepository.GetDb().Insertable<WarnEnvironmentEntity>(entity).ExecuteReturnIdentity();

                    retList.Add(isWarn);

                    SetHandled(ealyWarnTypeEnum, entity.ComNo); // 标记为已处理

                    if (isWarn)
                    {
                        string influence = "未及时处理";
                        string treatmentMethod = "请及时处理";
                        if (GetDicRemark(ealyWarnTypeEnum, out string temp1, out string temp2))
                        {
                            influence = temp1;
                            treatmentMethod = temp2;
                        }

                        NotificationEntity noticeEntity = new NotificationEntity()
                        {
                            Mold = (int)ealyWarnTypeEnum,
                            NoticeTime = DateTime.Now,
                            Describe = content,
                            Level = 1,
                            IsHandle = 1,
                            IsIgnore = 1,
                            Influence = influence,
                            TreatmentMethod = treatmentMethod,
                            OrganId = entity.OrganId,
                            OrganName = entity.OrganName,
                            ComNo = entity.ComNo,
                            CheckId = enId, // 物品ID、箱子ID、环境ID
                            CreateTime = DateTime.Now,
                            IsDeleted = false
                        };

                        EarlyWarnEnvironment(ealyWarnTypeEnum, noticeEntity);

                        //推送
                        dto.webScoketContents.Add(new WebScoketContent
                        {
                            Mold = (int)ealyWarnTypeEnum,
                            MolldTitle = "环境报警",
                            NoticeTime = DateTime.Now,
                            Describe = content,
                            Level = 1,
                        });
                        System.Threading.Thread.Sleep(50);
                    }
                }
                if (userIds.Count > 0)
                {
                    SendWarning(dto, userIds); // 数据推送UI
                }
                return new BaseGenericResult<bool>(retList.Any(x => x == true)); // 
            }
            catch(Exception)
            {
                return new BaseGenericResult<bool>(false);
            }
        }

        /// <summary>
        /// 环境报警
        /// </summary>
        /// <param name="ealyWarnTypeEnum">类型</param>
        /// <returns>是否成功</returns>
        public bool EarlyWarnEnvironment(EalyWarnTypeEnum ealyWarnTypeEnum, NotificationEntity entity)
        {
            //if (!GetStatus<EnvironmentalWarning>(WarningCategory.EnvironmentalWarning, out EnvironmentalWarning environmentalWarning)) return false;
            if (!GetStatus(out ConfigRequestDto configRequestDto)) return false;
            var environmentalWarning = configRequestDto.environmentalWarning;

            int minutes = 0;
            switch (ealyWarnTypeEnum)
            {
                case EalyWarnTypeEnum.eTemperatureWarning:
                    minutes = environmentalWarning.TemperatureMinute;
                    break;
                case EalyWarnTypeEnum.eHumidityWarning:
                    minutes = environmentalWarning.HumidityMinute;
                    break;
                case EalyWarnTypeEnum.eSmokeWarning:
                    minutes = environmentalWarning.SmogMinute;
                    break;
                case EalyWarnTypeEnum.eWaterWarning:
                    minutes = environmentalWarning.WaterMinute;
                    break;
                case EalyWarnTypeEnum.eAirWarning:
                    minutes = environmentalWarning.AirMinute;
                    break;
            }

            // 1. 查询     NotificationEntity的最大时间
            // 2.跟当前时间比较，如果大于当前时间，为不合格数据
            // 1）更改 回复时间，已处理
            // 2)插入NotificationEntity

            //查询上一次的起止日期 todo
            DateTime dt = GetMaxCreateTime(ealyWarnTypeEnum);
            DateTime dtNow = DateTime.Now;
            //List<NotificationEntity> notificationEntityList = _notificationRepository.GetDb().Queryable<NotificationEntity>()
            //    .Where(v => v.Mold == (int)ealyWarnTypeEnum && v.CreateTime >= dt && v.CreateTime <= DateTime.Now.AddMinutes(-minutes)).ToList();

            var totalMin = dtNow - dt;

            //if (totalMin.TotalMinutes >= minutes) // 不进行时间判断
            {
                _notificationRepository.GetDb().Insertable<NotificationEntity>(entity).ExecuteCommandAsync();

            }

            return true;
        }

        /// <summary>
        /// 保存超期
        /// </summary>
        /// <returns>是否成功</returns>
        public bool EarlyWarnOvertimeSave()
        {
            try
            {
                //if (!GetStatus<OvertimeSaveWarning>(WarningCategory.OvertimeSaveWarning, out OvertimeSaveWarning overtimeSaveWarning)) return false;
                if (!GetStatus(out ConfigRequestDto configRequestDto)) return false;
                var overtimeSaveWarning = configRequestDto.overtimeSaveWarning;

                if (!overtimeSaveWarning.Status) return false;
                int residueMinute = overtimeSaveWarning.ResidueMinute;
                int beOverdueMinute = overtimeSaveWarning.BeOverdueMinute;

                //查询上一次的起止日期
                DateTime dt = _notificationRepository.GetDb().Queryable<NotificationEntity>().Where(v => v.Mold == (int)EalyWarnTypeEnum.OvertimeSaveWarning && v.Remark == "0").Max(v => v.CreateTime); // 正常流程
                if (dt == null || dt == DateTime.MinValue)
                    dt = DateTime.Now.Date.AddYears(-1);
                List<CasePhysicalEvidenceTransfereEntity> entityList = _casePhysicalEvidenceTransfereRepository.GetDb().Queryable<CasePhysicalEvidenceTransfereEntity>()
                    .Where(v => !v.IsDeleted && (v.DeliveryDicType == 7 || v.DeliveryDicType == 8) && v.CreateTime >= dt
                        && ((overtimeSaveWarning.ResidueChecked && v.ReturnTime != null && v.ReturnTime.Value >= DateTime.Now.AddMinutes(residueMinute))  // 剩余时间提醒
                        || (overtimeSaveWarning.BeOverdueChecked && v.ReturnTime != null && v.ReturnTime.Value <= DateTime.Now.AddMinutes(-beOverdueMinute))) // 逾期提醒
                        && v.ReturnTime != null) // 正常流程：处置意见 不为空    保存期限 不为空
                     .ToList();

                WebScoketReqDto dto = new WebScoketReqDto();

                string influence = "未及时处理";
                string treatmentMethod = "请及时处理";
                if (GetDicRemark(EalyWarnTypeEnum.OvertimeSaveWarning, out string temp1, out string temp2))
                {
                    influence = temp1;
                    treatmentMethod = temp2;
                }

                foreach (var entity in entityList)
                {
                    string content = string.Empty;
                    var caseEvidence = _casePhysicalEvidenceTransfereRepository.GetDb().Queryable<CasePhysicalEvidenceEntity>().Where(v => v.Id == entity.EvidenceId).First();
                    if (caseEvidence != null)
                    {
                        content = string.Format($"{overtimeSaveWarning.PopContent}", caseEvidence.Name, caseEvidence.No);
                    }

                    _notificationRepository.GetDb().Insertable(new NotificationEntity()
                    {
                        Mold = (int)EalyWarnTypeEnum.OvertimeSaveWarning,
                        NoticeTime = DateTime.Now,
                        Describe = content,
                        Level = 2,
                        IsHandle = 1,
                        IsIgnore = 1,
                        Influence = influence,
                        TreatmentMethod = treatmentMethod,
                        OrganId = entity.OrganId,
                        OrganName = entity.OrganName,
                        ComNo = entity.ComNo,
                        CheckId = entity.EvidenceId, // 物品ID
                        CheckTime = entity.ReturnTime, // 回库时间
                        CreateTime = DateTime.Now,
                        IsDeleted = false,
                        Remark = "0",
                    }).ExecuteCommandAsync();

                    //推送
                    dto.webScoketContents.Add(new WebScoketContent
                    {
                        Mold = (int)EalyWarnTypeEnum.OvertimeSaveWarning,
                        MolldTitle = "保存超期预警",
                        NoticeTime = DateTime.Now,
                        Describe = content,
                        Level = 2,
                    });
                }

                SendWarning(dto, entityList.Select(v=>v.CreatorId.Value).ToList()); // 数据推送UI

                EarlyWarnOvertimeSaveDisposalOpinions(); // 处置意见
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex);
                return false;
            }

            return true;
        }

        /// <summary>
        /// 保存超期
        /// </summary>
        /// <returns>是否成功</returns>
        public bool EarlyWarnOvertimeSaveDisposalOpinions()
        {
            try
            {
                //if (!GetStatus<OvertimeSaveWarning>(WarningCategory.OvertimeSaveWarning, out OvertimeSaveWarning overtimeSaveWarning)) return false;
                if (!GetStatus(out ConfigRequestDto configRequestDto)) return false;
                var overtimeSaveWarning = configRequestDto.overtimeSaveWarning;

                if (!overtimeSaveWarning.Status) return false;

                //查询上一次的起止日期
                DateTime dt = _notificationRepository.GetDb().Queryable<NotificationEntity>().Where(v => v.Mold == (int)EalyWarnTypeEnum.OvertimeSaveWarning && v.Remark == "1").Max(v => v.CreateTime); // 处置意见
                if (dt == null || dt == DateTime.MinValue)
                    dt = DateTime.Now.Date.AddYears(-1);
                List<CasePhysicalEvidenceTransfereEntity> entityList = _casePhysicalEvidenceTransfereRepository.GetDb().Queryable<CasePhysicalEvidenceTransfereEntity>()
                    .Where(v => !v.IsDeleted && (v.DeliveryDicType == 7 || v.DeliveryDicType == 8) && v.CreateTime >= dt
                        && v.CreateTime <= DateTime.Now.AddHours(-overtimeSaveWarning.ResidueHour) // 处置时间
                        && !string.IsNullOrWhiteSpace(v.DisposalOpinions)) // 处置意见：处置意见 不为空  保存期限 为空
                     .ToList();

                WebScoketReqDto dto = new WebScoketReqDto();

                string influence = "未及时处理";
                string treatmentMethod = "请及时处理";
                if (GetDicRemark(EalyWarnTypeEnum.OvertimeSaveWarning, out string temp1, out string temp2))
                {
                    influence = temp1;
                    treatmentMethod = temp2;
                }

                foreach (var entity in entityList)
                {
                    string content = string.Empty;
                    var caseEvidence = _casePhysicalEvidenceTransfereRepository.GetDb().Queryable<CasePhysicalEvidenceEntity>().Where(v => v.Id == entity.EvidenceId).First();
                    if (caseEvidence != null)
                    {
                        content = string.Format($"{overtimeSaveWarning.NpopContent}", caseEvidence.Name, caseEvidence.No, entity.DisposalOpinions); // DisposalOpinions
                    }

                    _notificationRepository.GetDb().Insertable(new NotificationEntity()
                    {
                        Mold = (int)EalyWarnTypeEnum.OvertimeSaveWarning,
                        NoticeTime = DateTime.Now,
                        Describe = content,
                        Level = 2,
                        IsHandle = 1,
                        IsIgnore = 1,
                        Influence = influence,
                        TreatmentMethod = treatmentMethod,
                        OrganId = entity.OrganId,
                        OrganName = entity.OrganName,
                        ComNo = entity.ComNo,
                        CheckId = entity.EvidenceId, // 物品ID
                        CheckTime = entity.ReturnTime, // 回库时间
                        CreateTime = DateTime.Now,
                        IsDeleted = false,
                        Remark = "1",
                    }).ExecuteCommandAsync();

                    //推送
                    dto.webScoketContents.Add(new WebScoketContent
                    {
                        Mold = (int)EalyWarnTypeEnum.OvertimeSaveWarning,
                        MolldTitle = "保存超期预警",
                        NoticeTime = DateTime.Now,
                        Describe = content,
                        Level = 2,
                    });
                }

                SendWarning(dto, entityList.Select(v => v.CreatorId.Value).ToList()); // 数据推送UI
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex);
                return false;
            }

            return true;
        }

        /// <summary>
        /// 库容爆仓
        /// </summary>
        /// <returns>是否成功</returns>
        public bool EarlyWarnStockQuantity()
        {
            try
            {
                //if (!GetStatus<StockQuantityWarning>(WarningCategory.StockQuantityWarning, out StockQuantityWarning stockQuantityWarning)) return false;
                if (!GetStatus(out ConfigRequestDto configRequestDto)) return false;
                var stockQuantityWarning = configRequestDto.stockQuantityWarning;

                if (!stockQuantityWarning.Status) return false;
                int greaterVolumeMinute = stockQuantityWarning.GreaterOrEqualVolumeMinute;
                int lessVolumeMinute = stockQuantityWarning.LessVolumeMinute;

                double greaterVolume = stockQuantityWarning.GreaterOrEqualVolume;
                double lessVolume = stockQuantityWarning.LessVolume;

                //查询上一次的起止日期
                DateTime dt = GetMaxCreateTime(EalyWarnTypeEnum.eStockQuantityWarning);

                List<RoomBoxEntity> entityList = _roomBoxRepository.GetDb().Queryable<RoomBoxEntity>()
                    .Where(v => !v.IsDeleted && v.CreateTime >= dt
                        && ((stockQuantityWarning.GreaterOrEqualVolumeChecked && v.EviCount.HasValue && (v.EviCount.Value >= v.Total + greaterVolume) && v.CreateTime >= DateTime.Now.AddMinutes(-greaterVolumeMinute))
                        || (stockQuantityWarning.LessVolumeChecked && v.EviCount.HasValue && (v.EviCount.Value <= v.Total - lessVolume) && v.CreateTime <= DateTime.Now.AddMinutes(-lessVolumeMinute))))
                     .ToList();

                SetHandled(EalyWarnTypeEnum.eStockQuantityWarning,""); // 标记为已处理

                WebScoketReqDto dto = new WebScoketReqDto();

                string influence = "未及时处理";
                string treatmentMethod = "请及时处理";
                if (GetDicRemark(EalyWarnTypeEnum.eStockQuantityWarning, out string temp1, out string temp2))
                {
                    influence = temp1;
                    treatmentMethod = temp2;
                }

                foreach (var entity in entityList)
                {
                    string content = string.Empty;
                    var tup = _notificationRepository.GetBoxInfo(entity.Id);
                    if (tup != null)
                    {
                        content = string.Format($"{stockQuantityWarning.PopContent}", tup.Item1, tup.Item2, tup.Item3);
                    }
                    
                    _notificationRepository.GetDb().Insertable(new NotificationEntity()
                    {
                        Mold = (int)EalyWarnTypeEnum.eStockQuantityWarning,
                        NoticeTime = DateTime.Now,
                        Describe = content,
                        Level = 2,
                        IsHandle = 1,
                        IsIgnore = 1,
                        Influence = influence,
                        TreatmentMethod = treatmentMethod,
                        OrganId = entity.OrganId,
                        OrganName = entity.OrganName,
                        ComNo = "",
                        CheckId = entity.Id, // 箱子ID
                        CreateTime = DateTime.Now,
                        IsDeleted = false
                    }).ExecuteCommandAsync();

                    //推送
                    dto.webScoketContents.Add(new WebScoketContent
                    {
                        Mold = (int)EalyWarnTypeEnum.eStockQuantityWarning,
                        MolldTitle = "库存容量预警",
                        NoticeTime = DateTime.Now,
                        Describe = content,
                        Level = 2,
                    });
                }

                SendWarning(dto, entityList.Select(v => v.CreatorId.Value).ToList()); // 数据推送UI

            }
            catch (Exception ex)
            {
                return false;
            }

            return true;
        }

        public bool SendTestMsg()
        {
            WebSocketModel.SendJson(Newtonsoft.Json.JsonConvert.SerializeObject(new { test = "123" }), new List<string>());
            return true;
        }

        /// <summary>
        /// 数据推送UI
        /// </summary>
        /// <param name="dto"></param>
        private void SendWarning(WebScoketReqDto dto,List<long> userIds)
        {
            if (dto != null && dto.webScoketContents != null && dto.webScoketContents.Count > 0)
            {
                var userCodes = new List<string>();
                if (userIds.Count > 0)
                {
                    string sql = $" select `UserNo`  from system_user where `Id` in({string.Join(",", userIds)}) ";
                    userCodes = _roomBoxRepository.GetDb().Ado.SqlQuery<MainUserEntity>(sql).Select(v=>v.UserNo).ToList();
                }
                WebSocketModel.SendWarning(dto, userCodes);
            }
        }

        /// <summary>
        /// 获取预警类型
        /// </summary>
        /// <typeparam name="T">预警类型</typeparam>
        /// <param name="categoryCode">分类</param>
        /// <param name="dto">预警对象</param>
        /// <returns>是否成功</returns>
        private bool GetStatus(out ConfigRequestDto configDto)
        {
            configDto = new ConfigRequestDto();
            MainConfigEntity mainConfigEntity = new MainConfigEntity();
            var linq = _mainConfigRepository.GetDb().Queryable<MainConfigEntity>();
            if (linq == null) return false;

            var cfgEvidenceUnbound = linq.Where(m => m.IsDeleted == false && m.Class == "Warn").First();
            if (cfgEvidenceUnbound == null) return false;

            configDto = Newtonsoft.Json.JsonConvert.DeserializeObject<ConfigRequestDto>(cfgEvidenceUnbound.Content);
            if (configDto == null) return false;

            return true;
        }

        /// <summary>
        /// 根据EalyWarnTypeEnum标记为已处理
        /// </summary>
        /// <param name="ealyWarnTypeEnum">枚举</param>
        /// <returns>是否成功</returns>
        private bool SetHandled(EalyWarnTypeEnum ealyWarnTypeEnum,string comNo)
        {
            // 标记为已处理
            var entityList = _notificationRepository.GetDb().Queryable<NotificationEntity>().Where(x => x.Mold == (int)ealyWarnTypeEnum && x.ComNo == comNo && x.IsHandle == 1).ToList();
            if (entityList == null || entityList.Count == 0)
            {
                return true;
            }
            entityList.ForEach(x => x.IsHandle = 0);
            if (_notificationRepository.GetDb().Updateable(entityList).ExecuteCommand() > 0) 
                return true;
            return false;
        }

        /// <summary>
        /// 根据EalyWarnTypeEnum获取最大时间
        /// </summary>
        /// <param name="ealyWarnTypeEnum">枚举</param>
        /// <returns>最大时间</returns>
        private DateTime GetMaxCreateTime(EalyWarnTypeEnum ealyWarnTypeEnum)
        {
            //报错判断 Max
            var dt = _notificationRepository.GetDb().Queryable<NotificationEntity>().Where(v => v.Mold == (int)ealyWarnTypeEnum).Max(v => v.CreateTime);
            if (dt == null) dt = DateTime.Now.Date.AddYears(-1);
            return dt;
        }

        /// <summary>
        /// 从字典中获取备注
        /// </summary>
        /// <param name="ealyWarnTypeEnum">EalyWarnTypeEnum枚举</param>
        /// <param name="influence">影响</param>
        /// <param name="treatment">处理方式</param>
        /// <returns>是否成功</returns>
        private bool GetDicRemark(EalyWarnTypeEnum ealyWarnTypeEnum, out string influence, out string treatment)
        {
            influence = string.Empty;
            treatment = string.Empty;
            DicQueryDto dicQuery = new DicQueryDto();
            switch(ealyWarnTypeEnum)
            {
                case EalyWarnTypeEnum.eNoBindWarning:
                    dicQuery.DicCode = "1234561";
                    break;
                case EalyWarnTypeEnum.eOvertimeStockWarning:
                    dicQuery.DicCode = "1234562";
                    break;
                case EalyWarnTypeEnum.eOvertimeRevertWarning:
                    dicQuery.DicCode = "1234563";
                    break;
                case EalyWarnTypeEnum.eUnusualLevelWarning:
                    dicQuery.DicCode = "1234564";
                    break;
                case EalyWarnTypeEnum.eTemperatureWarning:
                    dicQuery.DicCode = "1234565";
                    break;
                case EalyWarnTypeEnum.eHumidityWarning:
                    dicQuery.DicCode = "1234566";
                    break;
                case EalyWarnTypeEnum.eSmokeWarning:
                    dicQuery.DicCode = "1234567";
                    break;
                case EalyWarnTypeEnum.eWaterWarning:
                    dicQuery.DicCode = "1234568";
                    break;
                case EalyWarnTypeEnum.eAirWarning:
                    dicQuery.DicCode = "1234569";
                    break;
                case EalyWarnTypeEnum.OvertimeSaveWarning:
                    dicQuery.DicCode = "12345610";
                    break;
                case EalyWarnTypeEnum.eStockQuantityWarning:
                    dicQuery.DicCode = "12345611";
                    break;
                case EalyWarnTypeEnum.eAuditingWarning:
                    dicQuery.DicCode = "12345612";
                    break;
                default:
                    break;
            }

            // MainDicEntity dic = _mainDicRepository.GetPagerList(dicQuery).Data.FirstOrDefault();
            MainDicEntity dic = _mainDicRepository.GetDb().Queryable<MainDicEntity>().Where(x => x.IsDeleted == false && x.Code == dicQuery.DicCode).First();
            if (dic != null && !string.IsNullOrWhiteSpace(dic.Remark))
            {
                string[] remarkList = dic.Remark.Split(DicRemarkSeparator, StringSplitOptions.None);
                if (remarkList != null && remarkList.Length > 1)
                {
                    influence = remarkList[0];
                    treatment = remarkList[1];
                    return true;
                }
            }

            return false;
        }

        #endregion 预警内部接口

        #region 查询：预警信息

        /// <summary>
        /// 查询：物品未绑定
        /// </summary>
        /// <param name="warnRequestDto">参数</param>
        /// <returns>信息</returns>
        public BaseGenericResult<Pager<WarnBindDto>> QueryWarnEvidenceUnbound(WarnRequestDto warnRequestDto)
        {
            return _notificationRepository.GetWarnEvidenceUnbound(warnRequestDto);
        }

        /// <summary>
        /// 查询：未及时入库
        /// </summary>
        /// <param name="warnRequestDto">参数</param>
        /// <returns>信息</returns>
        public BaseGenericResult<Pager<WarnBindDto>> QueryWarnOvertimeStock(WarnRequestDto warnRequestDto)
        {
            return _notificationRepository.GetWarnOvertimeStock(warnRequestDto);
        }

        /// <summary>
        /// 查询：未及时回库
        /// </summary>
        /// <param name="warnRequestDto">参数</param>
        /// <returns>信息</returns>
        public BaseGenericResult<Pager<WarnBindDto>> QueryWarnOvertimeRevert(WarnRequestDto warnRequestDto)
        {
            return _notificationRepository.GetWarnOvertimeRevert(warnRequestDto);
        }

        /// <summary>
        /// 查询：出库异常
        /// </summary>
        /// <param name="warnRequestDto">参数</param>
        /// <returns>信息</returns>
        public BaseGenericResult<Pager<WarnBindDto>> QueryWarnEvidenceStock(WarnRequestDto warnRequestDto)
        {
            return _notificationRepository.GetWarnEvidenceStock(warnRequestDto);
        }

        /// <summary>
        /// 查询：环境异常
        /// </summary>
        /// <param name="warnRequestDto">参数</param>
        /// <returns>信息</returns>
        public BaseGenericResult<Pager<WarnEnvironmentDto>> QueryWarnEnvironment(WarnEnvironmentRequestDto warnRequestDto)
        {
            return _notificationRepository.GetWarnEnvironment(warnRequestDto);
        }

        /// <summary>
        /// 查询：保存超期
        /// </summary>
        /// <param name="warnRequestDto">参数</param>
        /// <returns>信息</returns>
        public BaseGenericResult<Pager<WarnBindDto>> QueryWarnOvertimeSave(WarnRequestDto warnRequestDto)
        {
            return _notificationRepository.GetWarnOvertimeSave(warnRequestDto);
        }

        /// <summary>
        /// 查询：库容爆仓
        /// </summary>
        /// <param name="warnRequestDto">参数</param>
        /// <returns>信息</returns>
        public BaseGenericResult<Pager<WarnStockQuantityDto>> QueryWarnStockQuantity(WarnStockQuantityRequestDto warnRequestDto)
        {
            //if (!GetStatus<StockQuantityWarning>(WarningCategory.StockQuantityWarning, out StockQuantityWarning stockQuantityWarning)) return new BaseGenericResult<List<WarnStockQuantityDto>>();
            if (!GetStatus(out ConfigRequestDto configRequestDto)) return new BaseGenericResult<Pager<WarnStockQuantityDto>>();
            var stockQuantityWarning = configRequestDto.stockQuantityWarning;

            return _notificationRepository.GetWarnStockQuantity(warnRequestDto, stockQuantityWarning);
        }

        #endregion  查询：预警信息

        /// <summary>
        /// 获取所有父字典
        /// </summary>
        /// <returns></returns>
        public BaseGenericResult<Pager<NotificationResult>> QueryParentNotification(NotificationPagerReqDto reqDto)
        {
            var pagerEntity = _notificationRepository.GetPagerList(reqDto);
            Pager<NotificationResult> pager = new Pager<NotificationResult>();
            pager.TotalCount = pagerEntity.TotalCount;
            pager.Data = Util.AutoMapperExtension.MapTo<NotificationEntity, NotificationResult>(pagerEntity.Data);

      

            return BaseGenericResult<Pager<NotificationResult>>.Succeed(pager);
        }

        /// <summary>
        /// 未查看数据数量
        /// </summary>
        /// <returns></returns>
        public BaseGenericResult<string> DeleteNotificationByIds(BaseQuery reqDto)
        {
            var lst = _notificationRepository.Query(reqDto).ToList();
            foreach (var item in lst)
            {
                item.IsDeleted = true;
                item.Modifyer = reqDto.UserName;
                item.ModifyerId = reqDto.UserId;
                item.ModifyerTime = DateTime.Now;
                _notificationRepository.GetDb().Updateable(item).ExecuteCommand();

            }
            return new BaseGenericResult<string>() { Success = true };
        }
        


        /// <summary>
        /// 未查看数据数量
        /// </summary>
        /// <returns></returns>
        public BaseGenericResult<int> NotificationCount(BaseOperator reqDto)
        {
            if (reqDto == null) return new BaseGenericResult<int>(0);

            long notificationId = _notificationRepository.GetDb().Queryable<NoticeLogEntity>().Where(x => x.UserId == reqDto.UserId).Max(x => x.NotificationId);
            int count = _notificationRepository.GetDb().Queryable<NotificationEntity>().Where(x => x.IsDeleted == false && x.IsHandle != 0).Count(x => x.Id > notificationId);
            return new BaseGenericResult<int>(count);
        }

        /// <summary>
        /// 清空个人未查看数量
        /// </summary>
        /// <returns></returns>
        public BaseGenericResult<bool> ClearNotificationCount(long userId)
        {

            long notificationId = _notificationRepository.GetDb().Queryable<NotificationEntity>().Max(x => x.Id);
            NoticeLogEntity noticeLogEntity = new NoticeLogEntity() { UserId = userId, NotificationId = notificationId, Creator = $"{userId}" };
            _noticeLogRepository.GetDb().Insertable<NoticeLogEntity>(noticeLogEntity).ExecuteCommandAsync();
            return new BaseGenericResult<bool>(true);
        }

        #region 处理：预警信息

        /// <summary>
        /// 处理：物证相关预警
        /// </summary>
        /// <param name="casePhysicalEvidenceIdList">物证ID</param>
        /// <param name="handlePerson">处理人</param>
        /// <returns>是否成功</returns>
        public bool HandleWarnCases(List<long> caseIdList, string handlePerson)
        {
            return _notificationRepository.HandleWarnCases(caseIdList, handlePerson);
        }

        /// <summary>
        /// 处理：物品未绑定
        /// </summary>
        /// <param name="casePhysicalEvidenceIdList">物证ID</param>
        /// <returns>是否成功</returns>
        public bool HandleWarnEvidenceUnbound(List<long> casePhysicalEvidenceIdList, string handlePerson)
        {
            return _notificationRepository.HandleWarnEvidenceUnbound(casePhysicalEvidenceIdList, handlePerson);
        }

        /// <summary>
        /// 处理：未及时入库
        /// </summary>
        /// <param name="casePhysicalEvidenceIdList">物证ID</param>
        /// <returns>是否成功</returns>
        public bool HandleWarnOvertimeStock(List<long> casePhysicalEvidenceIdList, string handlePerson)
        {
            return _notificationRepository.HandleWarnOvertimeStock(casePhysicalEvidenceIdList, handlePerson);
        }

        /// <summary>
        /// 处理：未及时回库
        /// </summary>
        /// <param name="casePhysicalEvidenceIdList">物证ID</param>
        /// <returns>是否成功</returns>
        public bool HandleWarnOvertimeRevert(List<long> casePhysicalEvidenceIdList, string handlePerson)
        {
            return _notificationRepository.HandleWarnOvertimeRevert(casePhysicalEvidenceIdList, handlePerson);
        }

        /// <summary>
        /// 处理：出库异常
        /// </summary>
        /// <param name="casePhysicalEvidenceIdList">物证ID</param>
        /// <returns>是否成功</returns>
        public bool HandleWarnEvidenceStock(List<long> casePhysicalEvidenceIdList, string handlePerson)
        {
            return _notificationRepository.HandleWarnEvidenceStock(casePhysicalEvidenceIdList, handlePerson);
        }

        /// <summary>
        /// 处理：保存超期
        /// </summary>
        /// <param name="casePhysicalEvidenceIdList">物证ID</param>
        /// <returns>是否成功</returns>
        public bool HandleWarnOvertimeSave(List<long> casePhysicalEvidenceIdList, string handlePerson)
        {
            return _notificationRepository.HandleWarnOvertimeSave(casePhysicalEvidenceIdList, handlePerson);
        }

        #endregion
    }
}
